package com.uniflow.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.uniflow.entity.ApiKey;
import com.uniflow.entity.AuditLogs;
import com.uniflow.mapper.ApiKeyMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * API密钥服务层
 * 
 * @author uniflow
 * @since 1.0.0
 */
@Service
public class ApiKeyService {
    
    @Autowired
    private ApiKeyMapper apiKeyMapper;
    
    @Autowired
    private ApiApplicationService apiApplicationService;
    
    @Autowired
    private AuditLogService auditLogService;
    
    /**
     * 分页查询API密钥
     */
    public IPage<ApiKey> getKeyPage(int pageNum, int pageSize, String appId, String accessKey, Boolean expired) {
        Page<ApiKey> page = new Page<>(pageNum, pageSize);
        return apiKeyMapper.selectKeyPage(page, appId, accessKey, expired);
    }
    
    /**
     * 根据ID查询API密钥
     */
    public ApiKey getKeyById(String id) {
        return apiKeyMapper.selectById(id);
    }
    
    /**
     * 根据访问密钥查询
     */
    public ApiKey getKeyByAccessKey(String accessKey) {
        return apiKeyMapper.selectByAccessKey(accessKey);
    }
    
    /**
     * 根据应用ID查询密钥列表
     */
    public List<ApiKey> getKeysByAppId(String appId) {
        return apiKeyMapper.selectByAppId(appId);
    }
    
    /**
     * 检查访问密钥是否存在
     */
    public boolean existsByAccessKey(String accessKey, String excludeId) {
        return apiKeyMapper.existsByAccessKey(accessKey, excludeId);
    }
    
    /**
     * 查询有效的密钥
     */
    public List<ApiKey> getValidKeys(String appId) {
        return apiKeyMapper.selectValidKeys(appId);
    }
    
    /**
     * 查询过期的密钥
     */
    public List<ApiKey> getExpiredKeys() {
        return apiKeyMapper.selectExpiredKeys();
    }
    
    /**
     * 查询即将过期的密钥
     */
    public List<ApiKey> getExpiringKeys(Integer days) {
        return apiKeyMapper.selectExpiringKeys(days);
    }
    
    /**
     * 创建API密钥
     */
    @Transactional
    public ApiKey createKey(ApiKey apiKey) {
        // 验证应用是否存在
        if (apiKey.getAppId() != null) {
            com.uniflow.entity.ApiApplication application = apiApplicationService.getApplicationById(apiKey.getAppId());
            if (application == null) {
                throw new RuntimeException("应用不存在，无法创建API密钥");
            }
            if (application.getStatus() != 1) {
                throw new RuntimeException("应用已禁用，无法创建API密钥");
            }
        }
        
        // 生成ID
        apiKey.setId(UUID.randomUUID().toString().replace("-", ""));
        
        // 生成访问密钥
        if (apiKey.getAccessKey() == null) {
            apiKey.setAccessKey(generateAccessKey());
        }
        
        // 生成密钥
        if (apiKey.getSecretKey() == null) {
            apiKey.setSecretKey(generateSecretKey());
        }
        
        // 设置创建时间
        apiKey.setCreatedAt(LocalDateTime.now());
        
        // 检查访问密钥是否重复
        if (apiKeyMapper.existsByAccessKey(apiKey.getAccessKey(), null)) {
            throw new RuntimeException("访问密钥已存在");
        }
        
        apiKeyMapper.insert(apiKey);
        
        // 记录审计日志
        recordAuditLog("CREATE", "API_KEY", apiKey.getId(), 
                      "创建API密钥: " + apiKey.getAccessKey(), "SUCCESS", null);
        
        return apiKey;
    }
    
    /**
     * 更新密钥过期时间
     */
    @Transactional
    public void updateExpiresAt(String id, LocalDateTime expiresAt) {
        apiKeyMapper.updateExpiresAt(id, expiresAt);
    }
    
    /**
     * 更新密钥权限
     */
    @Transactional
    public void updatePermissions(String id, String permissions) {
        apiKeyMapper.updatePermissions(id, permissions);
    }
    
    /**
     * 删除API密钥
     */
    @Transactional
    public void deleteKey(String id) {
        // 获取密钥信息用于审计日志
        ApiKey apiKey = apiKeyMapper.selectById(id);
        
        apiKeyMapper.deleteById(id);
        
        // 记录审计日志
        if (apiKey != null) {
            recordAuditLog("DELETE", "API_KEY", id, 
                          "删除API密钥: " + apiKey.getAccessKey(), "SUCCESS", null);
        }
    }
    
    /**
     * 批量删除过期密钥
     */
    @Transactional
    public int deleteExpiredKeys() {
        return apiKeyMapper.deleteExpiredKeys();
    }
    
    /**
     * 查询密钥总数
     */
    public Long getTotalCount() {
        return apiKeyMapper.selectTotalCount();
    }
    
    /**
     * 查询有效密钥数
     */
    public Long getValidCount() {
        return apiKeyMapper.selectValidCount();
    }
    
    /**
     * 查询过期密钥数
     */
    public Long getExpiredCount() {
        return apiKeyMapper.selectExpiredCount();
    }
    
    /**
     * 查询今日新增密钥数
     */
    public Long getTodayNewCount() {
        return apiKeyMapper.selectTodayNewCount();
    }
    
    /**
     * 查询密钥使用统计
     */
    public List<Map<String, Object>> getUsageStats(String keyId, String startDate, String endDate) {
        return apiKeyMapper.selectUsageStats(keyId, startDate, endDate);
    }
    
    /**
     * 查询密钥调用频率统计
     */
    public List<Map<String, Object>> getCallFrequencyStats() {
        return apiKeyMapper.selectCallFrequencyStats();
    }
    
    /**
     * 查询密钥权限分布
     */
    public List<Map<String, Object>> getPermissionDistribution() {
        return apiKeyMapper.selectPermissionDistribution();
    }
    
    /**
     * 查询密钥生命周期统计
     */
    public List<Map<String, Object>> getLifecycleStats() {
        return apiKeyMapper.selectLifecycleStats();
    }
    
    /**
     * 查询最近活跃的密钥
     */
    public List<ApiKey> getRecentActiveKeys(Integer limit) {
        return apiKeyMapper.selectRecentActiveKeys(limit);
    }
    
    /**
     * 查询长时间未使用的密钥
     */
    public List<ApiKey> getInactiveKeys(Integer days) {
        return apiKeyMapper.selectInactiveKeys(days);
    }
    
    /**
     * 查询高频使用的密钥
     */
    public List<ApiKey> getHighFrequencyKeys(Integer limit) {
        return apiKeyMapper.selectHighFrequencyKeys(limit);
    }
    
    /**
     * 查询密钥详情（包含应用信息）
     */
    public ApiKey getKeyWithApplication(String id) {
        return apiKeyMapper.selectWithApplication(id);
    }
    
    /**
     * 查询密钥安全统计
     */
    public Map<String, Object> getSecurityStats(String keyId) {
        return apiKeyMapper.selectSecurityStats(keyId);
    }
    
    /**
     * 查询密钥错误统计
     */
    public List<Map<String, Object>> getErrorStats(String keyId) {
        return apiKeyMapper.selectErrorStats(keyId);
    }
    
    /**
     * 查询密钥性能统计
     */
    public Map<String, Object> getPerformanceStats(String keyId) {
        return apiKeyMapper.selectPerformanceStats(keyId);
    }
    
    /**
     * 查询密钥IP访问统计
     */
    public List<Map<String, Object>> getIpAccessStats(String keyId) {
        return apiKeyMapper.selectIpAccessStats(keyId);
    }
    
    /**
     * 查询密钥时段访问统计
     */
    public List<Map<String, Object>> getHourlyAccessStats(String keyId) {
        return apiKeyMapper.selectHourlyAccessStats(keyId);
    }
    
    /**
     * 查询密钥月度统计
     */
    public List<Map<String, Object>> getMonthlyStats(String keyId, Integer months) {
        return apiKeyMapper.selectMonthlyStats(keyId, months);
    }
    
    /**
     * 验证密钥和应用的关联关系
     */
    public boolean validateKeyAppRelation(String accessKey, String appId) {
        return apiKeyMapper.validateKeyAppRelation(accessKey, appId);
    }
    
    /**
     * 查询密钥的权限列表
     */
    public List<String> getKeyPermissions(String accessKey) {
        return apiKeyMapper.selectKeyPermissions(accessKey);
    }
    
    /**
     * 检查密钥是否有指定权限
     */
    public boolean hasPermission(String accessKey, String permission) {
        return apiKeyMapper.hasPermission(accessKey, permission);
    }
    
    /**
     * 生成访问密钥
     */
    private String generateAccessKey() {
        return "ak_" + UUID.randomUUID().toString().replace("-", "").substring(0, 16);
    }
    
    /**
     * 生成密钥
     */
    private String generateSecretKey() {
        return "sk_" + UUID.randomUUID().toString().replace("-", "") + UUID.randomUUID().toString().replace("-", "");
    }
    
    /**
     * 记录审计日志
     */
    private void recordAuditLog(String action, String resourceType, String resourceId, 
                               String description, String status, String operatorId) {
        try {
            AuditLogs auditLog = new AuditLogs();
            auditLog.setUserId(operatorId);
            auditLog.setOperationType(action);
            auditLog.setResourceType(resourceType);
            auditLog.setResourceId(resourceId);
            auditLog.setOperationDesc(description);
            auditLog.setOperationResult(status);
            auditLog.setOperationTime(LocalDateTime.now());
            
            auditLogService.createAuditLog(auditLog);
        } catch (Exception e) {
            // 审计日志记录失败不应影响主业务流程
            System.err.println("记录审计日志失败: " + e.getMessage());
        }
    }
}